import threading
from datetime import datetime
from multiprocessing import Manager

from xbase_util.common_util import date2s
from xbase_util.db.bean import ConfigBean

from base.bean.beans import ProcedureEnum
from base.bean.status_enum import StatusEnum
from base.util.redis_util import redis_listener, UpdateStatusParams
from package.package import PacketUtil
from replace.replace_fields import replace_fields
from session.session import SessionUtil
from set_label.set_label import LabelUtil


class ApiUtil:
    default_catalogue = "/out/"

    @classmethod
    def get_default_catalogue(cls):
        return cls.default_catalogue

    @staticmethod
    def wrap_correct(data: any, msg=None):
        return {
            "code": 200,
            "msg": "ok" if msg is None else msg,
            "data": data
        }

    @staticmethod
    def wrap_error(msg: str = "", code: int = 501):
        return {
            "code": code,
            "msg": msg,
            "data": None,
        }

    @staticmethod
    def single_step(function_type, config: ConfigBean, base_config, redisUtil, geoUtil, esdb):
        queue = Manager().Queue()
        threading.Thread(target=redis_listener, args=(queue, redisUtil, None)).start()
        queue.put(UpdateStatusParams(status=StatusEnum.processing.value,
                                     execStartTime=date2s(datetime.now()),
                                     execEndTime="", error="", fileList=[]))
        is_success = False
        if function_type == "session":
            is_success = SessionUtil.handle_session(config=config, base_config=base_config, queue=queue,
                                                    geoUtil1=geoUtil)
        if function_type == "pcap":
            is_success = PacketUtil.get_pcap(config, base_config, queue, esdb)
        if function_type == "extract_pcap":
            is_success = PacketUtil.extract_pcap(config, base_config['pcap']['path_prefix'], esdb)
        if function_type == "label":
            is_success = LabelUtil.set_label(config, base_config, queue)
        # if function_type == "mapping":
        #     is_success = MappingUtil.generate_mapping(config, queue)
        if function_type == "replace":
            is_success = replace_fields(config, queue, geoUtil)
        if is_success:
            queue.put(UpdateStatusParams(status=StatusEnum.finished.value,
                                         execEndTime=date2s(datetime.now())))
            queue.put(None)

    @staticmethod
    def background_task_flow(flow, config, base_config, redisUtil, geoUtil, esdb):
        queue = Manager().Queue()
        threading.Thread(target=redis_listener, args=(queue, redisUtil, None)).start()

        queue.put(UpdateStatusParams(status=StatusEnum.processing.value,
                                     execStartTime=date2s(datetime.now()),
                                     execEndTime="", error="", fileList=[], procedure=ProcedureEnum.none.value))
        step = flow.step
        is_success = False
        if "session" in step:
            is_success = SessionUtil.handle_session(config, base_config, queue, geoUtil)
        if "pcap" in step and is_success:
            is_success = PacketUtil.get_pcap(config=config, base_config=base_config, queue=queue, esdb=esdb)
        if "extract_pcap" in step and is_success:
            is_success = PacketUtil.extract_pcap(config, base_config['pcap']['path_prefix'], esdb)
        if "label" in step and is_success:
            is_success = LabelUtil.set_label(config=config, base_config=base_config, queue=queue)
        # if "mapping" in step and is_success:
        #     is_success = MappingUtil.generate_mapping(config=config, queue=queue)
        if "replace" in step and is_success:
            is_success = replace_fields(config, queue, geoUtil)
        if is_success:
            queue.put(UpdateStatusParams(status=StatusEnum.finished.value,
                                         execEndTime=date2s(datetime.now())))
            queue.put(None)

    @staticmethod
    def saveDataExtractionTask(config, callBackUrl, requestCode, base_config, redisUtil, geoUtil, esdb):
        print(f"saveDataExtractionTask接口  requestCode:{requestCode}   callBackUrl:{callBackUrl} ")
        shared_dict = Manager().dict()
        shared_dict['requestCode'] = requestCode
        shared_dict['callBackUrl'] = callBackUrl
        queue = Manager().Queue()
        threading.Thread(target=redis_listener, args=(queue, redisUtil, shared_dict)).start()
        queue.put(UpdateStatusParams(status=StatusEnum.finished.value,
                                     execStartTime=date2s(datetime.now()),
                                     execEndTime="",
                                     procedure=ProcedureEnum.none.value, error="", fileList=[]))
        is_success = SessionUtil.handle_session(config, base_config, queue, geoUtil)
        if is_success:
            is_success = PacketUtil.get_pcap(config=config, base_config=base_config, queue=queue, esdb=esdb)
        if is_success:
            is_success = LabelUtil.set_label(config=config, base_config=base_config, queue=queue)
        if is_success:
            queue.put(
                UpdateStatusParams(status=StatusEnum.finished.value,
                                   execEndTime=date2s(datetime.now()),
                                   procedure=ProcedureEnum.none.value))
            queue.put(None)
